/*
 * iPersona.cpp
 *
 *  Created on: 05/07/2014
 *      Author: nicolas
 */

#include "iPersona.h"
#include <syslog.h>
#include <stdio.h>
#include <sstream>
#include <unistd.h>

using namespace std;

iPersona::iPersona(int numero, Tipos::LugarDeSala lugar) {
	this->lugar = lugar;
	this->numero = numero;
	this->colaSistema = new ColaMensajes(RUTA, COLASISTEMA);
	this->colaRespuesta = new ColaInterfaz(RUTA, COLARECIBO_CLI);
	this->idSalaEntradaCola = rpc.pedirIdSala(numero, Tipos::TP_ENTRADA_COLA,
			lugar);
	this->idSalaEntradaSala = rpc.pedirIdSala(numero, Tipos::TP_ENTRADA_SALA,
			lugar);
	this->idSalaSalida = rpc.pedirIdSala(numero, Tipos::TP_SALIDA, lugar);

}

void iPersona::permitirAscenso(int idPersona) {
//	long int idSala = rpc.pedirIdSala(numero, Tipos::TP_SALIDA, lugar);
//	long int idSala = idServer.idSala(numero, Tipos::TP_SALIDA, lugar);
	MENSAJE msg;
	msg.destinatario = idSalaSalida;
	msg.destinatarioFinal = idPersona;
	msg.origen = idSalaSalida;
	msg.tipo = Tipos::MSJ_SUBIR_PERSONA_A_BUS;
	colaSistema->enviar(&msg, TAM_MENSAJE);
	syslog(LOG_INFO,
			"Se envio el mensaje: destinatario: %li, origen: %li, id: %i, respuesta: %i",
			msg.destinatario, msg.origen, msg.id, msg.respuesta);
}

void iPersona::recibirInformeAscenso() {
//	long int idSala = rpc.pedirIdSala(numero, Tipos::TP_SALIDA, lugar);
//	long int idSala = idServer.idSala(numero, Tipos::TP_SALIDA, lugar);
	MENSAJE msg;
	//colaRespuesta->recibir(&msg, TAM_MENSAJE, idSalaSalida);
	colaRespuesta->recibirMensaje(msg, Tipos::MSJ_CONFIRMAR_SUBIDA_A_BUS,
			idSalaSalida);
	if (msg.tipo != Tipos::MSJ_CONFIRMAR_SUBIDA_A_BUS)
		syslog(LOG_ERR,
				"Error de tipo de mensaje esperado, esperado: %i, recibido: %i",
				(int) Tipos::MSJ_CONFIRMAR_SUBIDA_A_BUS, (int) msg.tipo);
	syslog(LOG_INFO,
			"Se recibio el mensaje: destinatario: %li, origen: %li, id: %i, respuesta: %i",
			msg.destinatario, msg.origen, msg.id, msg.respuesta);
}

int iPersona::recibirPeticionEntrar() {
//	long int idSala = rpc.pedirIdSala(numero, Tipos::TP_ENTRADA_COLA, lugar);
//	long int idSala = idServer.idSala(numero, Tipos::TP_ENTRADA_COLA, lugar);

	static bool corte = false;

	if (!corte) {
		generarCorte(idSalaEntradaCola);
		generarCorte(idSalaEntradaSala);
		corte = true;
	}
	MENSAJE msg;
	//colaRespuesta->recibir(&msg, TAM_MENSAJE, idSalaEntradaCola);
	colaRespuesta->recibirMensaje(msg, Tipos::MSJ_ENTRAR_COLA_DE_SALA,
			idSalaEntradaCola);

	if (msg.tipo != Tipos::MSJ_ENTRAR_COLA_DE_SALA)
		syslog(LOG_ERR,
				"Error de tipo de mensaje esperado, esperado: %i, recibido: %i",
				(int) Tipos::MSJ_ENTRAR_COLA_DE_SALA, (int) msg.tipo);
	syslog(LOG_INFO,
			"Se recibio el mensaje: destinatario: %li, origen: %li, id: %i, respuesta: %i",
			msg.destinatario, msg.origen, msg.id, msg.respuesta);
	return msg.origen;
}

void iPersona::permitirAcceso(int id) {
//	long int idSala = rpc.pedirIdSala(numero, Tipos::TP_ENTRADA_COLA, lugar);
//	long int idSala = idServer.idSala(numero, Tipos::TP_ENTRADA_COLA, lugar);
	MENSAJE msg;
	msg.destinatario = idSalaEntradaCola;
	msg.destinatarioFinal = id;
	msg.origen = idSalaEntradaCola;
	msg.tipo = Tipos::MSJ_ENTRAR_EN_SALA;
	colaSistema->enviar(&msg, TAM_MENSAJE);
	syslog(LOG_INFO,
			"Se envio el mensaje: destinatario: %li, origen: %li, id: %i, respuesta: %i",
			msg.destinatario, msg.origen, msg.id, msg.respuesta);
}

void iPersona::generarCorte(int id) {
	stringstream idAux;
	idAux << id;
	int pid = fork();
	if (pid == 0) {
		execlp("./conexBrokerCliente", "conexBrokerCliente",
				idAux.str().c_str(), "E", NULL);
		perror("Error en el exec conexionBrokerCliente");
		exit(1);
	}
	pid = fork();
	if (pid == 0) {
		execlp("./conexBrokerCliente", "conexBrokerCliente",
				idAux.str().c_str(), "R", NULL);
		perror("Error en el exec conexionBrokerCliente");
		exit(1);
	}
}

void iPersona::recibirInformeAcceso() {
//	long int idSala = rpc.pedirIdSala(numero, Tipos::TP_ENTRADA_SALA, lugar);
//	long int idSala = idServer.idSala(numero, Tipos::TP_ENTRADA_SALA, lugar);

	MENSAJE msg;
	//colaRespuesta->recibir(&msg, TAM_MENSAJE, idSalaEntradaSala);
	colaRespuesta->recibirMensaje(msg, Tipos::MSJ_CONFIRMAR_ENTRADA_A_SALA,
			idSalaEntradaSala);
	if (msg.tipo != Tipos::MSJ_CONFIRMAR_ENTRADA_A_SALA)
		syslog(LOG_ERR,
				"Error de tipo de mensaje esperado, esperado: %i, recibido: %i",
				(int) Tipos::MSJ_CONFIRMAR_ENTRADA_A_SALA, (int) msg.tipo);
	syslog(LOG_INFO,
			"Se recibio el mensaje: destinatario: %li, origen: %li, id: %i, respuesta: %i",
			msg.destinatario, msg.origen, msg.id, msg.respuesta);
}
